﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Cofe.Core.Validater;
using NaturalSorting;

namespace Cofe.Core
{
    public class PropertyPairComparer : IComparer<PropertyPair>
    {
        private static NaturalComparer naturalComparer = new NaturalComparer();
        public static PropertyPairComparer Instance = new PropertyPairComparer();

        public PropertyPairComparer()
        {

        }

        public int Compare(PropertyPair x, PropertyPair y)
        {
            if (x.Value == null)
                return 1;
            if (y.Value == null)
                return -1;

            var propertyType = PropertyTypeExtension.GetDefaultPropertyType(x.Property);
            switch ((int)x.Property)
            {
                case (int)CofeProperties.FullParseName:
                case (int)CofeProperties.Label:
                    return naturalComparer.Compare(x.ValueAsString, y.ValueAsString);
            }

            switch (propertyType.ToString())
            {
                case "System.Int32":
                    return x.ValueAsInt32.CompareTo(y.ValueAsInt32);
                case "System.Int64":
                    return x.ValueAsInt64.CompareTo(y.ValueAsInt64);
                case "System.DateTime":
                    return x.ValueAsLocalDateTime.CompareTo(y.ValueAsLocalDateTime);
                default:
                    return x.Value.ToString().CompareTo(y.Value.ToString());
            }

        }
    }

    public class PropertyPairEqualityComparer : IEqualityComparer<PropertyPair>
    {

        public static PropertyPairEqualityComparer ComparePropertyValueOnly = new PropertyPairEqualityComparer(false, true);
        public static PropertyPairEqualityComparer ComparePropertyOnly = new PropertyPairEqualityComparer(true, false);
        public static PropertyPairEqualityComparer CompareBoth = new PropertyPairEqualityComparer(true, true);

        private Func<PropertyPair, PropertyPair, bool> _compareFunc = null;
        private Func<PropertyPair, int> _hashFunc = null;

        private PropertyPairEqualityComparer(bool compareProperty, bool compareValue)
        {
            _compareFunc = (pp1, pp2) =>
                {
                    if (compareProperty)
                        if (!(pp1.Property.Equals(pp2.Property)))
                            return false;
                    if (compareValue)
                        if (!(pp1.Value.Equals(pp2.Value)))
                            return false;
                    return true;
                };

            _hashFunc = (pp) =>
                {
                    if (compareProperty && compareValue)
                        return pp.Value.GetHashCode() + pp.Property.GetHashCode();
                    else if (compareProperty)
                        return pp.Property.GetHashCode();
                    else
                        return pp.Value.GetHashCode();
                };
        }

        public bool Equals(PropertyPair x, PropertyPair y)
        {
            return _compareFunc(x, y);
        }

        public int GetHashCode(PropertyPair obj)
        {
            return _hashFunc(obj);
        }
    }
}
